<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My Vocabulary</title>
    <link rel="stylesheet" href="/css/style.css">
    <link rel="stylesheet" href="/css/print.css" media="print">
</head>

<body>
    <div class="app page" v-cloak>
        <article>
            <div class="flex-row title not-print">
                <p class="sn">No.</p>
                <p class="word">Word</p>
                <p class="flex-1">Meaning</p>
                <p><span class="underline" @click="() => visible = true">arrange</span></p>
                <p><span class="underline" @click="() => remoteSync(1)">remote sync</span></p>
            </div>
            <word-row v-for="(x, y) in list.filter(it => it.hide !== true)" :key="x.itemId" :data="x" :sn="y + 1" />
        </article>
        <div class="modal-container">
            <Transition>
                <div class="mask" v-show="visible"></div>
            </Transition>
            <Transition>
                <div class="modal flex-column" v-show="visible">
                    <div class="modal-title">Words To Learn</div>
                    <div class="modal-body">
                        <word-group :source="list" @group="createGroup" type="origin"></word-group>
                        <word-group :class="{selected: x.selected}" :source="x.data" :group-name="x.name" v-for="(x) in newGroups" :key="x.name" @select="selectGroup" @delete="deleteGroup"></word-group>
                    </div>
                    <div class="modal-footer">
                        <span class="word-item" @click="() => visible = false">return</span>
                        <span class="word-item" type="primary" @click="onArrange">render by group</span>
                    </div>
                </div>
            </Transition>
        </div>
    </div>

    <script src="/js/vue.global.js"></script>
    <script>
        function throttle(fn, delay) {
            let last = 0;
            return function (...args) {
                const now = +new Date();
                if (now - last > delay) {
                    last = now;
                    fn.apply(this, args);
                }
            }
        }
        const app = Vue.createApp({
            data() {
                return {
                    list: [],
                    newGroups: [],
                    visible: false
                }
            },
            mounted() {
                this.remoteSync()
                this.initGroup()
            },
            methods: {
                remoteSync(isSync = 0) {
                    fetch(`/wordlist?sync=${isSync}`).then(res => res.json()).then(res => {
                        this.list = res.data.itemList
                    })
                },
                onArrange() {
                    this.visible = false
                    const selectedGroup = this.newGroups.find(it => it.selected)
                    if (selectedGroup) {
                        this.list = selectedGroup.data
                    }
                },
                initGroup() {
                    const groups = localStorage.getItem('groups')
                    if (groups) this.newGroups = JSON.parse(groups)
                },
                createGroup(name, data) {
                    if (this.newGroups.find(it => it.name === name)) {
                        return alert(`name '${name}'' is repeated!`)
                    }
                    if (!name) return
                    this.newGroups.push({ name, data })
                    localStorage.setItem('groups', JSON.stringify(this.newGroups))
                },
                selectGroup(name, data) {
                    this.newGroups = this.newGroups.map((it) => {1
                        it.selected = (it.name === name)
                        return it
                    })
                },
                deleteGroup(name) {
                    if (confirm(`Are you sure you want to delete the group ${name}`)) {
                        this.newGroups = this.newGroups.filter((it) => it.name !== name)
                        localStorage.setItem('groups', JSON.stringify(this.newGroups))
                    }
                }
            }
        })

        const SentenceMore = Vue.defineComponent({
            props: ['source'],
            template: `
                <div style="padding: 15px 25px" :class="{'not-print': !flag}">
                    <span class="underline" @click="() => (flag = !flag)">e.g.</span>
                    <div class="details-item" v-if="flag">
                        <p class="prefix-line sentence" v-for="(x, y) in source" :key="y">{{x}}</p>
                    </div>
                </div>
            `,
            data() {
                return {
                    flag: false
                }
            }
        })
        const WordRow = Vue.defineComponent({
            props: ['data', 'sn'],
            template: `
                <div class="word-row">
                    <div class="flex-row">
                        <p class="sn">{{ sn }}</p>
                        <p class="word">
                            <span style="margin-right: 10px">{{ data.word }}</span>
                            <span class="phonogram" style="margin-right: 10px">
                                <i v-show="data.ukphone">/{{data.ukphone}}/</i>
                            </span>
                        </p>
                        <p class="flex-1">
                            <span>{{ data?.trans }}</span>
                        </p>
                        <span class="not-print underline" @click="() => deleteWord(data.itemId)">delete</span>
                        <span class="not-print underline" @click="() => (flag = !flag) && !data.details && getDetails(data.itemId, data.word)">details</span>
                    </div>
                    <div class="details" v-show="flag">
                        <ul>
                            <li class="details-item" v-for="(x, y) in data.details" :key="y">
                                <p class="meaning">{{x.meaning}}</p>
                                <div v-for="(a, b) in x.examples" :key="y + '' + b">
                                    <p class="prefix-line sentence">{{a.sentence}}</p>
                                    <p class="trans">{{a.trans}}</p>
                                </div>
                            </li>
                        </ul>
                        <sentence-more v-if="data.more?.length" :source="data.more"></sentence-more>
                    </div>
                </div>
            `,
            data() {
                return {
                    flag: false
                }
            },
            methods: {
                async getDetails(id, word) {
                    const { more, details } = await fetch(`/sentence?word=${word}`).then(res => res.json())
                    this.data.more = more
                    this.data.details = details
                },
                async deleteWord(id) {
                    if (confirm('确定删除吗？')) {
                        await fetch(`/wordelete?id=${id}`).then(res => res.json())
                    }
                }
            }
        })
        const WordGroup = Vue.defineComponent({
            props: ['source', 'groupName', 'type'],
            template: `
                <div :class="{'word-group': type !== 'origin'}">
                    <p v-if="type !== 'origin'" class="group-name" @click="$emit('select', groupName, list)">{{groupName || 'default'}}</p>
                    <transition-group tag="ul" name="fade" class="word-list">
                        <div :class="{'word-item': true, 'selected': x.hide !== true}"
                            v-for="(x, y) in list" :key="x.itemId" @click="() => toggle(x.itemId)"
                            draggable="true"
                            @dragstart="($event) => dragStart($event, y)"
                            @dragover="($event) => dragoOver($event, y)"
                            @drop="($event) => drop($event, y)"    
                        >
                            {{x.word}}
                        </div>
                    </transition-group>
                    <p class="flex-row">
                        <input type="checkbox" id="scales" name="scales" :checked="list.every(it => it.hide !== true)" @click="selectAll">
                        <label for="scales">全选</label>
                        <span>，共{{list.length}}条，已选{{list.filter(it => it.hide !== true).length}}。</span>
                        <span v-if="type === 'origin'"><input type="text" placeholder="group name" v-model="gname" /> </span>
                        <button v-if="type === 'origin'" class="word-item" @click="() => $emit('group', gname, list.filter(it => it.hide !== true))">create group</button>
                        <span style="flex: 1"></span>
                        <span v-if="type !== 'origin'" class="" @click="() => $emit('delete', groupName)"><i style="cursor: pointer">delete</i></span>
                    </p>
                </div>
            `,
            data() {
                return {
                    list: [],
                    gname: ''
                }
            },
            watch: {
                source(n) {
                    this.list = JSON.parse(JSON.stringify(n))
                }
            },
            mounted() {
                this.list = JSON.parse(JSON.stringify(this.source))
            },
            methods: {
                toggle(itemId) {
                    this.list = this.list.map(it => {
                        if (it.itemId === itemId) {
                            it.hide = !it.hide
                        }
                        return it
                    })
                },
                selectAll(e) {
                    this.list = this.list.map(it => {
                        it.hide = !e.target.checked
                        return it
                    })
                },
                dragoOver(e, index) {
                    e.preventDefault();
                },
                dragStart(e, index) {
                    e.dataTransfer.setData('fromIndex', index);
                },
                drop(e, to) {
                    e.preventDefault();
                    const from = e.dataTransfer.getData('fromIndex');
                    const list = [...this.list]
                    list.splice(to, 0, list.splice(from, 1)[0])
                    this.list = list;
                }
            }
        })
        app.component('SentenceMore', SentenceMore)
        app.component('WordRow', WordRow)
        app.component('WordGroup', WordGroup)
        app.mount('.app')
    </script>
</body>

</html>